using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace ScrumSim
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        public GraphicsDeviceManager graphics { get; set; }
        public SpriteBatch spriteBatch { get; set; }

        public RenderTarget2D mTarget;

        public Texture2D mScreenTitle;

        Level mLevel;
        Player mGo;

        List<GameObject> mPlateforme;

        Song mSong;

        SpriteFont  mFont;
        bool mDeadScreen;
        bool mStartingScreen;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 166 * 5;
            graphics.PreferredBackBufferHeight = 140 * 5;
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            mDeadScreen = false;
            mStartingScreen = true;

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            mFont = Content.Load<SpriteFont>("Defaut");

            mSong = Content.Load<Song>("02-overworld");

            mTarget = new RenderTarget2D(GraphicsDevice, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);

            mScreenTitle = Content.Load<Texture2D>("titleScreen");

            StartNewGame();
            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (mStartingScreen)
            {
                KeyboardState lState = Keyboard.GetState();
                if (lState.IsKeyDown(Keys.Enter))
                {
                    mStartingScreen = false;
                    StartNewGame();
                }
            }
            else if (!mDeadScreen)
            {
                this.mLevel.Update(gameTime);

                base.Update(gameTime);

                mGo.HandleEnvironnement(mLevel.plateforms, mLevel.enemies);

                if (mGo.dead)
                {
                    MediaPlayer.Stop();
                    mDeadScreen = true;
                }

                /*int y = (int)(mGo.position.Y - mLevel.getY());

                if(Math.Abs(y) < 100)*/
                    mLevel.setY((int)(mGo.position.Y - graphics.PreferredBackBufferHeight * 0.5f));
            }
            else
            {
                KeyboardState lState = Keyboard.GetState();
                if (lState.IsKeyDown(Keys.Enter))
                {
                    mDeadScreen = false;
                    MediaPlayer.Play(mSong);
                    StartNewGame();
                }
            }
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.SetRenderTarget(mTarget);

            GraphicsDevice.Clear(Color.Olive);

            // TODO: Add your drawing code here

            if (mStartingScreen)
            {
                spriteBatch.Begin();

                spriteBatch.Draw(mScreenTitle, new Rectangle(0, 0, mTarget.Width, mTarget.Height), Color.Olive);
             
                spriteBatch.End();
            }
            else if (!mDeadScreen)
            {
                spriteBatch.Begin();

                base.Draw(gameTime);

                spriteBatch.DrawString(mFont, ((int)mLevel.GetDX()).ToString(), Vector2.Zero, Color.Black);

                spriteBatch.End();
            }
            else
            {
                spriteBatch.Begin();

                spriteBatch.DrawString(mFont, "DEFAITE! \n Score :"+(int)(mLevel.GetDX())+" \n\n Appuyez sur Entree pour recommencer.", new Vector2(100.0f, graphics.PreferredBackBufferHeight * 0.5f), Color.Black); 

                spriteBatch.End();
            }

            GraphicsDevice.SetRenderTarget(null);
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone);
            spriteBatch.Draw(mTarget, new Rectangle(0,0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight), Color.White);
            spriteBatch.End();
        }

        public Level GetLevel()
        {
            return mLevel;
        }

        //---------------------------------------------------------

        public void StartNewGame()
        {
            Components.Clear();

            mLevel = new Level(this);
            mGo = new Player(this);

            /*mPlateforme = new List<GameObject>();

            for (int i = 0; i < 50; i++)
            {
                mPlateforme.Add(new GameObject(this, "RedRect", new Vector2(i * 64, 400), new Rectangle(0, 0, 64, 64), new Rectangle(0, 0, 64, 64)));
                Components.Add(mPlateforme[i]);
            }*/

            Components.Add(mGo);
            mGo.position = new Vector2(300, 100);

            mLevel.Init();
        }
    }
}
